const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const parameter = require('koa-parameter')
const {tokenError} = require('./utils/errMsg.type')

const handleErr = require('./utils/handleErr.js')
const router = require('./index')
const JWT = require('./utils/jwt.js')
// onerror(app)
const { interError, notfoundError} = require('./utils/errMsg.type')

var cors = require('koa2-cors');

app.use(cors()); // 允许跨域


// middlewares 解析前端数据格式
app.use(bodyparser({
  enableTypes:['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))

// 设置模板引擎ejs 服务端渲染
app.use(views(__dirname + '/views', {
  extension: 'ejs'
}))

// logger日志
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

app.use(parameter(app))
// 验证token
app.use(async (ctx, next) => {
  // index接口放行
  // if (ctx.url.includes("index")) {
  //   await next()
  //   return
  // }
  // login已经获得token,其他接口进来必须校验
  const token = ctx.header.authorization
  if (token) {
    const payload = JWT.verify(token) // 解密
    // console.log(payload);
    if (payload) {
      // 验证通过重新计算token
      const newtoken = JWT.generate({
        uid: payload.userId, // 测试
      }, '1d')
      ctx.set('Authorization', newtoken)
      await next()
    } else {
      ctx.app.emit('errMsg', tokenError, ctx)
    }
  }else{
      await next() // 这里放行要靠前端做限制
  }
})

// src/middlewares/catchError.js

const  catchError  = async (ctx, next) => {
  try {
    await next()
    if (ctx.status === 404) { // 只是一个抛出自定义特定错误的示例
      ctx.app.emit('errMsg',notfoundError,ctx) // 并返回

      // throw new errs.NotFound()
    }
  } catch(err) {
    if (err.errorCode) { 
      // 如果是自己主动抛出的 HttpException类 错误
      ctx.status = err.status || 500
      ctx.body = {
        code: '0000',
        msg: '服务器错误'+err.message,
        errorCode: err.errorCode,
        request: `${ctx.method} ${ctx.path}`,
      }
    } else {
      // 触发 koa app.on('error') 错误监听事件，可以打印出详细的错误堆栈 log
      ctx.app.emit('error', err, ctx)
      ctx.app.emit('errMsg',interError,ctx) // 并返回
    }
  }
}
app.use(catchError)
// routes 应用级中间件
app.use(router.routes()).use(router.allowedMethods())

// error-handling 错误处理
app.on('error', (err, ctx) => {
  console.error('server error', err)
});

app.on('errMsg',handleErr)  // 抛出错误信息提示

module.exports = app
